from pathlib import Path
from pyecharts import options as opts
from pyecharts.charts import Line

class KeywordTrendGenerator:
    """关键词趋势折线图生成器"""
    
    def __init__(self):
        self.colors = [
            "#5470c6", "#91cc75", "#fac858",
            "#ee6666", "#73c0de", "#3ba272",
            "#fc8452", "#9a60b4", "#ea7ccc"
        ]
    
    def _validate_data(self, data, years):
        """验证数据有效性"""
        if not data:
            raise ValueError("没有趋势数据")
            
        for keyword, counts in data.items():
            if len(counts) != len(years):
                raise ValueError(
                    f"关键词 {keyword} 的数据点数量({len(counts)})与年份数量({len(years)})不匹配"
                )
            
            for count in counts:
                if not isinstance(count, (int, float)):
                    raise TypeError(f"关键词 {keyword} 包含非数字数据: {count}")
                if count < 0:
                    raise ValueError(f"关键词 {keyword} 包含负数: {count}")
    
    def generate(self, data, save_path, title=None):
        """生成关键词趋势折线图"""
        try:
            # 准备x轴数据(年份)
            years = [str(year) for year in range(2019, 2024)]
            
            # 验证数据
            self._validate_data(data, years)
            
            # 处理保存路径
            save_path = Path(save_path)
            save_path.parent.mkdir(parents=True, exist_ok=True)
            
            # 创建折线图实例
            line = Line(
                init_opts=opts.InitOpts(
                    width="600px",
                    height="350px",
                    bg_color="#ffffff"
                )
            )
            
            # 添加x轴数据
            line.add_xaxis(years)
            
            # 为每个关键词添加一条折线
            for idx, (keyword, counts) in enumerate(data.items()):
                line.add_yaxis(
                    series_name=keyword,
                    y_axis=counts,
                    is_symbol_show=True,
                    symbol_size=8,
                    label_opts=opts.LabelOpts(is_show=False),
                    linestyle_opts=opts.LineStyleOpts(width=2),
                    itemstyle_opts=opts.ItemStyleOpts(color=self.colors[idx % len(self.colors)])
                )
            
            # 设置全局配置
            line.set_global_opts(
                title_opts=opts.TitleOpts(
                    is_show=False,
                    title=title or "专利关键词趋势分析",
                    subtitle="2019-2023年",
                    pos_left="center",
                    title_textstyle_opts=opts.TextStyleOpts(
                        font_size=24,
                        color="#000"
                    )
                ),
                tooltip_opts=opts.TooltipOpts(
                    trigger="axis",
                    axis_pointer_type="cross"
                ),
                legend_opts=opts.LegendOpts(
                    is_show=False,
                    pos_top="10%",
                    pos_right="0%",
                    orient="vertical"
                ),
                xaxis_opts=opts.AxisOpts(
                    type_="category",
                    boundary_gap=False
                ),
                yaxis_opts=opts.AxisOpts(
                    type_="value",
                    name="专利数量",
                    name_location="end",
                    name_gap=15,
                    splitline_opts=opts.SplitLineOpts(is_show=True)
                )
            )
            
            # 渲染图表
            line.render(save_path)
            return str(save_path)
            
        except Exception as e:
            print(f"Error details: {str(e)}")
            raise